import ResponseConfig from '../models/ResponseConfig'
import HttpResponse from '../models/HttpResponse'
import HttpResponseHandler from '../models/HttpResponseHandler'
import { warn } from './feedback'
import { getEnvConfig, BUSINESS_ERROR_CODE_ESCAPE } from '../config/index'
import { mockRequest } from './mock/index'
import { getToken } from '../support/token'

// 处理响应的一些配置项
const responseConfig = new ResponseConfig({
  businessOkCode: '0',
  businessErrorCodeEscape: BUSINESS_ERROR_CODE_ESCAPE
})

// 定义响应处理器
const httpResponseHandler = new HttpResponseHandler({
  config: responseConfig,
  handleHttpError: ({ message }) => { warn(message) },
  handleBusinessError: ({ message }) => { warn(message) },
})

// 处理响应数据
async function handleResponseData (resp) {
  const { data, statusCode } = resp
  const httpResponse = new HttpResponse({
    data,
    code: statusCode
  })
  return await httpResponseHandler.handle(httpResponse)
}

// 给请求参数追加token
async function appendTokenToRequest (options) {
  const token = await getToken()
  if (!options.header) {
    options.header = {}
  }
  options.header.Authorization = `token=${token}`
  return options
}

// 加工请求参数
async function buildRequestOptions (options) {
  return await appendTokenToRequest(options)
}

async function request (url, options) {
  // 是否对响应进行模拟
  const { enabledApiMock } = getEnvConfig()
  if (enabledApiMock) {
    return await handleResponseData({ data: mockRequest(url), statusCode: 200 })
  }
  // 正常发起请求
  const requestOptions = await buildRequestOptions({ ...options, url })
  return new Promise((resolve, reject) => {
    wx.request({
      ...requestOptions,
      success: async (res) => {
        const result = await handleResponseData(res)
        resolve(result)
      },
      fail: err => {
        const msg = err.errno + err.errMsg
        warn(msg)
        reject(msg)
      }
    })
  })
}

export {
  request
}